package com.spz.demo.singleboot.controller;

import com.spz.demo.singleboot.common.CacheConst;
import com.spz.demo.singleboot.common.RequestMappingConst;
import com.spz.demo.singleboot.service.UserService;
import com.spz.demo.singleboot.util.*;
import com.spz.demo.singleboot.vo.Response;
import com.spz.demo.singleboot.exception.custom.RequestVariableException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 公用Controller接口
 * 此类中的接口均不需要身份验证
 */
@Slf4j
@Validated
@RestController
@RequestMapping(RequestMappingConst.BASIC_URL_PUBLIC)
public class PublicController {

    @Autowired
    private EhcacheUtil ehcacheUtil;
    @Autowired
    private UserService userService;
    @Autowired
    private FileUtil fileUtil;

    /**
     * 图片上传
     * @param image
     * @param imageType 1-租客身份证图片
     * @return
     */
    @PostMapping("/uploadImage")
    public Response uploadImage(MultipartFile image){
        String relativePath = FileUtil.RELATIVE_PATH_IMAGE + "/other/";
        String[] typeTemp = image.getContentType().split("/");
        if(typeTemp == null || typeTemp.length != 2){
            return Response.error("文件上传失败，无法解析文件类型： " + image.getContentType());
        }
        String fileName = FileUtil.createFileName() + "." + typeTemp[1];
        Response<Boolean> response = fileUtil.fileUpload(image,relativePath,fileName);
        if(response.getData() == false){
            return Response.error("文件上传失败");
        }else{
            log.debug("文件上传成功：" + relativePath + "/" + fileName);
        }

        Map<String,String> rest = new HashMap<>();
        rest.put("rootUtl",fileUtil.getUrl());
        rest.put("relativePath",relativePath + "/" + fileName);
        return Response.ok(rest);
    }

    /**
     * 生成图片验证码
     *
     * 关于keyCode：前端需要获取用户机器的唯一标识，如果无法获取，则需要前端生成一个随机不重复的字符串
     *              后台在生成验证码后，将以keyCode为key将验证码文字存储在缓存里
     *              前端在发起一次存在验证码参数的请求时，需要将keyCode再次作为请求参数发送，因为后台需要以此为key从缓存里获取验证码文字
     *              这样可以规避不同机器的验证码标识问题。
     *
     * @param keyCode 唯一机器标识
     * @return
     */
    @RequestMapping(value = "vCode/{keyCode}" , method = RequestMethod.GET)
    public void getVerifyCode(@PathVariable String keyCode,
                              HttpServletRequest request,
                              HttpServletResponse response)throws Exception {
        if(StringUtil.isBlank(keyCode)){
            throw new RequestVariableException("keyCode","缺少参数");
        }

        // 生成验证码
        String code = StringUtil.getRandomString(4);

        // 删除缓存（如果存在）
        ehcacheUtil.delete(CacheConst.IMAGE_CODE + keyCode);

        // 存入缓存
        ehcacheUtil.set(
                CacheConst.IMAGE_CODE + keyCode,
                code,
                1,// 使用后一秒失效
                60//生存时间60秒
        );

        // 输出到输出流
        BufferedImage image = ImageCode.getImageCode(60,20,code);
        if(!ControllerUtil.outPutImage(image,"png",response)){
            log.error("图片输出失败");
        }
    }

    /**
     * 获取字符串对应的MD5字符串
     * @param str
     * @return
     */
    @GetMapping("/md5/{str}")
    public Response getMd5(@PathVariable String str){
        if(StringUtil.isBlank(str)){
            return Response.paramError("参数不合法");
        }
        return Response.ok(StringUtil.md5(str));
    }

    // 测试用
    @GetMapping("/t")
    public String getCache(Integer a){
        if(a!=null && a == 1){
            ehcacheUtil.set("钥匙","值撒78旦法",10);
            return "put in cache: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        }else if(a!=null&&a==3){
            ehcacheUtil.delete("钥匙");
            return "delete cache";
        }
        else{
            String rest = ehcacheUtil.get("钥匙");
            rest += "   \n get cache：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            return rest;
        }
    }

}
